from common.entitys.caiptal import Flow
from utils import caiptal_util, price_util, k_util_v1, ave_util, dict_util
from database.mapper import funds_info, boards_info
from service import training_model


# 通用上下文
class CommonContext:
    def __init__(self, code):
        self.code = code
        self.name = None
        self.exchange = None
        self.rt_price = None  # 最新价格
        self.ave5 = None  # 5日均线价
        self.ave10 = None  # 10日均线价
        self.harden = None  # 涨停价格
        self.drop = None  # 跌停价格
        self.kp = None  # 开盘价格
        self.hundred_flow = None  # 百日资金流
        self.recently_jgcyd = None  # 机构参与度
        self.rt_flow = None  # 实时资金流
        self.fund_hold = None  # 持有的基金
        self.fund_hold_amt = None  # 持有的基金总金额
        self.day_k_new_n_dict = None  # 最近n条k
        self.board_belong = None  # 所属板块
        self.board_flow_all_dict = None  # 所有板块资金流
        self.train_model = None  # 训练模型

    def get_train_model(self):
        if self.train_model is None:
            self.train_model = training_model.train(self.code)
        return self.train_model

    def get_board_flow_all_dict(self):
        if self.board_flow_all_dict is None:
            self.board_flow_all_dict = caiptal_util.board_flow_info()
        return self.board_flow_all_dict

    # 获取所属于的板块
    def get_board_belong(self):
        if self.board_belong is None:
            s_b_list = boards_info.select_stock_code(self.code)
            board_dict = self.get_board_flow_all_dict()
            for sbi in s_b_list:
                bdi = dict_util.get_default(board_dict, str(sbi.get('board_code')), '')
                if bdi == '':
                    sbi['main_io'] = 0
                    sbi['zf'] = 0
                else:
                    sbi['main_io'] = bdi.get('main_io')
                    sbi['zf'] = bdi.get('zf')
            self.board_belong = sorted(s_b_list, key=lambda x: x['main_io'], reverse=True)
        return self.board_belong

    def get_kp(self):
        if self.kp is None:
            self.kp = self.get_day_k_new_n_dict(1)[0]['kp']
        return self.kp

    def get_drop(self):
        if self.drop is None:
            self.drop = round(self.get_day_k_new_n_dict(2)[1]['sp'] * 0.9, 2)
        return self.drop

    def get_harden(self):
        if self.harden is None:
            self.harden = round(self.get_day_k_new_n_dict(2)[1]['sp'] * 1.1, 2)
        return self.harden

    def get_ave5(self):
        if self.ave5 is None:
            self.ave5 = ave_util.ave_line_price(self.get_day_k_new_n_dict(10)[0:5], 5)
        return self.ave5

    def get_ave10(self):
        if self.ave10 is None:
            self.ave10 = ave_util.ave_line_price(self.get_day_k_new_n_dict(10), 10)
        return self.ave10

    def get_day_k_new_n_dict(self, size: int) -> list:
        if self.day_k_new_n_dict is None or len(self.day_k_new_n_dict) < size:
            self.day_k_new_n_dict = k_util_v1.day_k_size_rt(self.code, size, self.get_rt_price())
        return self.day_k_new_n_dict[0:size]

    def get_rt_price(self):
        if self.rt_price is None:
            self.rt_price = price_util.get_rt_p(self.code)
        return self.rt_price

    # 持有的基金总金额
    def get_fund_hold_amt(self):
        if self.fund_hold_amt is None:
            fund_hold_list = self.get_fund_hold()
            self.fund_hold_amt = 0
            for fund in fund_hold_list:
                self.fund_hold_amt += fund['stock_val']
        return self.fund_hold_amt

    # 获取持有的资金
    def get_fund_hold(self):
        if self.fund_hold is None:
            self.fund_hold = funds_info.select_by_stock_code(self.code)
        return self.fund_hold

    # 获取百日资金流
    def get_hundred_flow(self):
        if self.hundred_flow is None:
            self.hundred_flow = caiptal_util.flow_hundred(self.code)
        return self.hundred_flow

    # 获取机构参与度
    def get_recently_jgcyd(self):
        if self.recently_jgcyd is None:
            self.recently_jgcyd = caiptal_util.flow_jgcyd(self.code)
        return self.recently_jgcyd

    # 获取实时资金流
    def get_rt_flow(self) -> Flow:
        if self.rt_flow is None:
            self.rt_flow = caiptal_util.get_flow(self.code)
        return self.rt_flow
